图文详述Nacos配置中心使用:应用间配置共享、扩展配置文件加载优先级、新老版本差异

您所在的位置:网站首页 nacos 拉取配置 图文详述Nacos配置中心使用:应用间配置共享、扩展配置文件加载优先级、新老版本差异

图文详述Nacos配置中心使用:应用间配置共享、扩展配置文件加载优先级、新老版本差异

2024-05-08 13:54| 来源: 网络整理| 查看: 265

一、前言

项目上使用Nacos做为配置中心,以前使用的是Concul;现在准备详细梳理一下Nacos做为配置中心的配置文件加载优先级问题,因为以前在使用Consul的时候,由于配置文件优先级问题踩过大坑。

二、实战 1、集成Nacos配置中心

1) POM中引入SpringCloud、Spring Cloud Alibaba依赖,记得做好maven版本管理、否则存在版本问题一地鸡毛的场景。

2.3.7.RELEASE com.alibaba.cloud spring-cloud-starter-alibaba-nacos-config org.springframework.boot spring-boot-dependencies ${spring-boot.version} pom import org.springframework.cloud spring-cloud-dependencies Hoxton.SR8 pom import com.alibaba.cloud spring-cloud-alibaba-dependencies 2.2.5.RELEASE pom import

2) 在bootstrap.yml中配置Nacos-server的地址

server: port: 9001 spring: application: name: config1 # 配置名,即Nacos dashboard中的Data id cloud: nacos: config: server-addr: 127.0.0.1:8848 # 配置中心地址,集群的话多个节点使用,分隔 file-extension: yaml # 配置的后缀名 namespace: 2c38da96-f654-4105-bbc0-63befaa449f0 # 命名空间ID group: DEFAULT_GROUP # 指定要获取配置的组

在这里插入图片描述3) 随便写个Controller,用@Value等注解或ConfigurableApplicationContext获取配置信息。

import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; /** * @author zhouxin * @RefreshScope 动态加载配置 **/ @RefreshScope @RestController public class NacosServerController { @Resource private ConfigurableApplicationContext configurableApplicationContext; /** * 可用于验证本服务配置文件和extension-configs之间的优先级 */ @Value("${student.name:null}") private String name; /** * 如果只是通过@Value获得的配置信息,不会随着Nacos的修改操作而获得最新配置信息。那么,实时获取最新配置信息有两种方式: * 方式1:添加@RefreshScope注解。 * 方式2:通过getProperty的方式,获得最新的配置信息。 * * @return */ @GetMapping("/name") public String getName() { String name1 = configurableApplicationContext.getEnvironment().getProperty("student.name"); return String.format("name=%s name1=%s", name, name1); }

Nacos服务端config1.yaml配置如下:在这里插入图片描述启动服务,通过HTTP访问(http://localhost:9001/name)到的结果如下:在这里插入图片描述这说明:我们可以通过很多中方式注入配置,包括:@Value、@ConfigurationProperties、ConfigurableApplicationContext等。

2、应用配置共享

Nacos提供两种应用间共享配置的方式:扩展DataId(extension-configs)、共享DataId(shared-configs);另外需共享的DataId,yaml后缀不能少,且目前只支持yaml/properties。

0)Nacos服务端配置准备 (1)config1.yaml

在这里插入图片描述

(2)config2.yaml

在这里插入图片描述

(3)config3.yaml在这里插入图片描述 (4)config4.yaml

在这里插入图片描述

(5)config5.yaml

在这里插入图片描述

1)扩展Data Id配置

Spring Cloud Alibaba Nacos Config 从 0.2.1 版本后,可支持自定义扩展Data Id 配置,特性如下:

1、支持多个 Data Id 的配置;

通过 spring.cloud.nacos.config.extension-configs[n].data-id 的配置方式

2、可以自定义Data Id 所在的组,不明确配置的话,默认是 DEFAULT_GROUP;

通过 spring.cloud.nacos.config.extension-configs[n].group 的配置方式

3、当某个Data Id 的配置变更时,自定义应用中是否动态刷新配置值,默认为否;

通过 spring.cloud.nacos.config.extension-configs[n].refresh 的配置方式 源码中的体现:

(1)在bootstrap.yml文件中按住command 鼠标左键点extension-configs,进入如下源码:在这里插入图片描述从上面我们可以看出扩展DataID的主体是Config类,我们看一下它:在这里插入图片描述从这里我们便能看出上面提到的extension-configs的特性和一些默认值。

使用:

(1)bootstrap.yml文件中增加如下配置:

spring: cloud: nacos: config: # 使用extension-configs[n],配置加载多个dataId extension-configs: - data-id: config4.yaml group: CONFIG4_GROUP refresh: true # 动态刷新配置 - data-id: config5.yaml group: DEFAULT_GROUP refresh: true # 动态刷新配置

(2)controller中引入只存在于config4.yaml和config5.yaml中的配置:

@Value("${config4.name:null}") private String config4Name; @Value("${config5.name:null}") private String config5Name; @GetMapping("/allname") public String getAllName() { return String.format("config4Name=%s config5Name=%s", config4Name, config5Name); }

通过HTTP访问(http://localhost:9001/allname)到的结果如下:在这里插入图片描述

2)共享Data Id配置

为了更加清晰的在多个应用间配置共享的 Data Id ,也可以通过以下的方式来配置:

1、支持多个 Data Id 的配置;

通过 spring.cloud.nacos.config.shared-configs[n].data-id 的配置方式

2、可以自定义Data Id 所在的组,不明确配置的话,默认是 DEFAULT_GROUP;

通过 spring.cloud.nacos.config.shared-configs[n].group 的配置方式

3、当某个Data Id 的配置变更时,自定义应用中是否动态刷新配置值,默认为否;

通过 spring.cloud.nacos.config.shared-configs[n].refresh 的配置方式 使用:

(1)bootstrap.yml文件中增加如下配置:

spring: cloud: nacos: config: # 使用shared-config[n],配置加载多个dataId shared-configs: - data-id: config2.yaml group: DEFAULT_GROUP refresh: true # 动态刷新配置 - data-id: config3.yaml group: DEFAULT_GROUP refresh: true # 动态刷新配置

(2)controller中引入只存在于config2.yaml和config3.yaml中的配置:

@Value("${config2.name:null}") private String config2Name; @Value("${config3.name:null}") private String config3Name; @GetMapping("/allname") public String getAllName() { return String.format("config2Name=%s config3Name=%s", config2Name, config3Name); }

通过HTTP访问(http://localhost:9001/allname)到的结果如下:在这里插入图片描述

聪明的大家肯定发现这和extension-configs扩展DataId的方式一毛一样啊,是的,它就一毛一样。但是注意,在老版本中它俩的扩展方式还真不一样,下面我们来看一下新老版本扩展/共享DataId的差异?

3、扩展/共享DataId新老版本差异 1)老版本的pom 1.8 2.1.3.RELEASE Greenwich.RELEASE 2.1.0.RELEASE com.alibaba.cloud spring-cloud-alibaba-dependencies ${spring.cloud.alibaba} pom import org.springframework.cloud spring-cloud-dependencies ${spring.cloud} pom import org.springframework.boot spring-boot-dependencies ${spring.boot} pom import 2)扩展DataId方式的差异

新版本yaml中使用extension-configs,老版本yaml使用ext-config;除此之外,功能上并没有区别。在这里插入图片描述

3)分享DataId方式的差异

(1)使用上:

1、新版本yaml中使用 shared-configs; 2、老版本yaml使用 shared-dataids根据DataID加载配置信息、使用 refreshable-dataids实现指定DataId配置信息的动态刷新;

2)功能上:

新版本yaml中支持指定group,老版本中不支持指定Group,只会取默认的group-- DEFAULT_GROUP;

在这里插入图片描述为什么老版本不支持指定group呢?我们来看一下:

3)源码分析

(1) 在bootstrap.yml文件中按住command 鼠标左键点shared-dataids,进入如下源码:在这里插入图片描述

public static final String SEPARATOR = "[,]";

这里我们可以看到它会将传入的sharedDataids以,分隔为多个DataId,并将DataId作为入参构造Config:在这里插入图片描述其中只会指定dataId,并不会牵扯到group。

(2) 我们再看shared-dataids:在这里插入图片描述在这里插入图片描述它也只是将拆分出的所有dataId对应的Config的refresh属性设置为true,也不牵扯到group。

(3)会不会有group-dataids呢?进入NacosConfigProperties类中全局搜索一把,并没有。

好了,新老版本的差异我们也聊完了,下面看一下配置文件加载的优先级吧。

4、扩展的配置文件加载优先级

Spring Cloud Alibaba Nacos Config 目前提供了三种配置能力从 Nacos 拉取相关的配置;

A: 通过 spring.cloud.nacos.config.shared-configs[n].data-id 支持多个共享 Data Id 的配置; B: 通过 spring.cloud.nacos.config.extension-configs[n].data-id 的方式支持多个扩展 Data Id 的配置; C: 通过内部相关规则(应用名、应用名+ Profile )自动生成相关的 Data Id 配置;

当三种方式共同使用时,总的来说 他们的一个优先级关系是:A < B < C。

(1)以老版本来说:

1、shared-dataids中越靠后,优先级越高; 2、ext-config中n越大、或越靠后,优先级越高; 3、Shared-dataids < ext-config < 内部;

(2)以新版本来说:

1、shared-configs中n越大、或越靠后,优先级越高; 2、extension-configs中n越大、或越靠后,优先级越高; 3、shared-configs < extension-configs < 内部; 1)逻辑图

在这里插入图片描述相信大家看了这个图,也不需要做过多解释了。

2)代码 (1)controller: import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; /** * @author zhouxin * @RefreshScope 动态加载配置 **/ @RefreshScope @RestController public class NacosServerController { @Resource private ConfigurableApplicationContext configurableApplicationContext; /** * 可用于验证本服务配置文件和extension-configs之间的优先级 */ @Value("${student.name:null}") private String name; @Value("${config2.name:null}") private String config2Name; @Value("${config3.name:null}") private String config3Name; @Value("${config4.name:null}") private String config4Name; @Value("${config5.name:null}") private String config5Name; /** * 用于验证shared-configs之间的优先级 */ @Value("${config.name:null}") private String configName; /** * extension-configs和shared-configs的优先级 */ @Value("${ext.name:null}") private String extName; /** * 用于验证extension-configs之间的优先级 */ @Value("${ext.gender:null}") private String extGender; /** * 如果只是通过@Value获得的配置信息,不会随着Nacos的修改操作而获得最新配置信息。那么,实时获取最新配置信息有两种方式: * 方式1:添加@RefreshScope注解。 * 方式2:通过getProperty的方式,获得最新的配置信息。 * * @return */ @GetMapping("/name") public String getName() { String name1 = configurableApplicationContext.getEnvironment().getProperty("student.name"); return String.format("name=%s name1=%s", name, name1); } @GetMapping("/allname") public String getAllName() { return String.format("config1Name=%s config2Name=%s config3Name=%s config4Name=%s config5Name=%s configName=%s extName=%s extGender=%s", name, config2Name, config3Name, config4Name, config5Name, configName, extName, extGender); } } (2)新版本bootstrap.yml配置: server: port: 9001 spring: application: name: config1 cloud: nacos: config: # 此处的nacos用于配置管理 server-addr: 127.0.0.1:8848 file-extension: yaml namespace: 2c38da96-f654-4105-bbc0-63befaa449f0 # 命名空间ID group: DEFAULT_GROUP # 指定要获取配置的组 shared-configs: - data-id: config2.yaml refresh: true - data-id: config3.yaml refresh: true extension-configs: - data-id: config4.yaml group: CONFIG4_GROUP refresh: true # 动态刷新配置 - data-id: config5.yaml group: DEFAULT_GROUP refresh: true # 动态刷新配置 (3)老版本bootstrap.yml配置: server: port: 9001 spring: application: name: config1 # 配置名 cloud: nacos: config: server-addr: 127.0.0.1:8848 # 配置中心地址——单机 file-extension: yaml # 后缀名 namespace: 2c38da96-f654-4105-bbc0-63befaa449f0 # 命名空间ID group: DEFAULT_GROUP # 指定要获取配置的组 # 使用shared-dataids,配置加载多个dataId shared-dataids: config2.yaml,config3.yaml refreshable-dataids: config2.yaml # 使用ext-config[n],配置加载多个dataId ext-config: - data-id: config4.yaml group: CONFIG4_GROUP refresh: true # 动态刷新配置 - data-id: config5.yaml group: DEFAULT_GROUP refresh: true # 动态刷新配置

在这里插入图片描述

5、本地和远程配置优先级

SpringCloud中,nacos是借助SpringCloud的Config来加载属性源的,所以是否覆盖系统属性和配置文件属性的设置也是通过SpringCloud的配置进行触发。

默认情况下nacos属性源配置优先级最高,会覆盖系统属性源和配置属性源(本地文件)。

可以通过在远程配置中心(Nacos服务中)中做如下配置,设置本地配置覆盖远程配置:

spring: cloud: config: # Nacos远程配置是否不覆盖其他属性源(文件、系统),默认为false,即覆盖其他源(文件、系统),当allow-override:为true时才会生效 override-none: true # 是否允许Nacos远程配置被本地文件覆盖,默认为true allow-override: true # Nacos远程配置是否可以覆盖系统属性源(系统环境变量或系统属性),默认为true,即允许 override-system-properties: false

在这里插入图片描述

注意:

1、将其放在bootstrap.yml或application.yml配置文件中是无效的。 2、如果allow-override值为false,即使将override-none设置为true,也是无效的。 6、其他

通过设置 spring.cloud.nacos.config.enabled = false 来完全关闭 Spring Cloud Nacos Config;

更多Nacos-config的内容请参考Nacos的GitHub Wiki:https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-config

三、最佳实践

仁者见仁智者见智,仅供参考;

1、能放本地、不放远程;避免滥用远程服务器; 2、尽量规避优先级; 3、定规则,例如所有配置属性都要加上注释; 4、配置管理人员尽量少;

最后,虽然我用的Nacos1.4.1版本,但是不建议大家在生产环境使用这个版本,因为该版本存在一个致命的bug:

客户端与 Nacos Server 如果发生短暂的域名解析问题,会导致心跳永久丢失,进而引发服务全量下线,即使网络恢复,也不会自动恢复心跳。

域名解析失败常见于网络抖动或者 K8s 环境下的 coreDNS 访问超时等场景,并且该问题仅存在于 1.4.1 版本,低于此版本不受此问题的影响,使用 1.4.1 的用户建议升级至 1.4.2 以避免此问题(源自阿里内部博文)。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3